home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 2: Applications
/
Linux Cubed Series 2 - Applications.iso
/
circuits
/
pcb-1.000
/
pcb-1
/
pcb-1.3
/
dialog.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-27
|
11KB
|
419 lines
/*
* COPYRIGHT
*
* PCB, interactive printed circuit board design
* Copyright (C) 1994,1995 Thomas Nau
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contact addresses for paper mail and Email:
* Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
* Thomas.Nau@rz.uni-ulm.de
*
*/
static char *rcsid = "$Header: /sda4/users/nau/src/pcb/RCS/dialog.c,v 2.1 1994/09/28 14:26:08 nau Exp $";
/* dialog routines
*/
#include <stdlib.h>
#include "global.h"
#include "data.h"
#include "dialog.h"
#include "error.h"
#include "mymem.h"
#include "misc.h"
#include <X11/Shell.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Toggle.h>
/* ---------------------------------------------------------------------------
* include the icon data
*/
#include "icon.data"
/* ---------------------------------------------------------------------------
* some local identifiers
*/
static int ReturnCode; /* used by standard dialogs */
/* ---------------------------------------------------------------------------
* some local prototypes
*/
static void CB_OK(Widget, XtPointer, XtPointer);
static void CenterDialog(Widget, Boolean, Boolean);
static void SendEnterNotify(void);
/* ---------------------------------------------------------------------------
* callback for standard dialog
* just copies the button-code which is passed as ClientData to a
* public identifier
*/
static void CB_OK(Widget W, XtPointer ClientData, XtPointer CallData)
{
ReturnCode = (int) ClientData;
}
/* ---------------------------------------------------------------------------
* centers the widget around the current cursor position
*/
static void CenterDialog(Widget Popup, Boolean CenterX, Boolean CenterY)
{
Window root, child;
int root_x, root_y,
child_x, child_y;
unsigned int mask;
Dimension width, height;
/* get current pointer position relativ to it's parent */
XQueryPointer(Dpy, XtWindow(Popup),
&root, &child,
&root_x, &root_y,
&child_x, &child_y,
&mask);
/* get the dialogs size */
XtVaGetValues(Popup,
XtNheight, &height,
XtNwidth, &width,
NULL);
/* make sure position is inside our screen */
if (CenterX)
if ((root_x -= (width/2)) < 0)
root_x = 0;
else
if (root_x > WidthOfScreen(XtScreen(Popup)) -width)
root_x = WidthOfScreen(XtScreen(Popup)) -width;
if (CenterY)
if ((root_y -= (height/2)) < 0)
root_y = 0;
else
if (root_y > HeightOfScreen(XtScreen(Popup)) -height)
root_y = HeightOfScreen(XtScreen(Popup)) -height;
XtVaSetValues(Popup,
XtNx, root_x,
XtNy, root_y,
NULL);
}
/* ---------------------------------------------------------------------------
* waits until returncode is differnt from -1
* see also CB_OK()
*/
int DialogEventLoop(int *Code)
{
XEvent event;
for(*Code = -1; *Code == -1;)
{
XtAppNextEvent(Context, &event);
XtDispatchEvent(&event);
}
return(*Code);
}
/* ---------------------------------------------------------------------------
* adds the buttons to a dialog
*/
Widget AddButtons(Widget Parent, Widget Top,
DialogButtonTypePtr Buttons, size_t Count)
{
int i;
for (i = 0; i < Count; i++)
{
/* skip button if there's no label,
* used for dialogs without default button
*/
if (!Buttons[i].Label)
continue;
Buttons[i].W = XtVaCreateManagedWidget(Buttons[i].Name,
commandWidgetClass,
Parent,
XtNlabel, Buttons[i].Label,
XtNfromHoriz, i ? Buttons[i-1].W : NULL,
XtNfromVert, Top,
XtNresizable, True,
NULL);
XtAddCallback(Buttons[i].W,
XtNcallback, Buttons[i].Callback, Buttons[i].ClientData);
}
return(Buttons[Count-1].W);
}
/* ---------------------------------------------------------------------------
* thanks to Ellen M. Sentovich and Rick L. Spickelm for their hint in
* xrn
*
* creates a dialog box as a child of ... (see arguments)
*/
Widget CreateDialogBox(char *LabelText,
DialogButtonTypePtr Buttons, size_t Count)
{
Widget dialog,
popup;
/* create the popup shell */
popup = XtVaCreatePopupShell("popup", transientShellWidgetClass,
Output.Toplevel,
XtNinput, True,
XtNallowShellResize, True,
NULL);
dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass,
popup,
XtNlabel, LabelText,
NULL);
/* now we add the buttons and install the accelerators */
AddButtons(dialog, NULL, Buttons, Count);
while (Count--)
XtInstallAccelerators(dialog, Buttons[Count].W);
return(popup);
}
/* ---------------------------------------------------------------------------
* pops up a dialog
* saves output window in pixmap
* first realize the dialog and
* focus keyboard events from the application to it
*/
void StartDialog(Widget Popup)
{
SaveOutputWindow();
XtRealizeWidget(Popup);
CenterDialog(Popup, True, True);
XtPopup(Popup, XtGrabExclusive);
}
/* ---------------------------------------------------------------------------
* removes a dialog from screen and from memory
* pixmap is released by next dialog
*/
void EndDialog(Widget Popup)
{
XtPopdown(Popup);
XtDestroyWidget(Popup);
XFlush(Dpy);
XSync(Dpy, False);
}
/* ---------------------------------------------------------------------------
* prints out a warning
*/
void MessageDialog(char *MessageText)
{
Widget popup;
static DialogButtonType buttons[] = {
{ "defaultButton", " OK ", CB_OK, (XtPointer) OK_BUTTON, NULL }};
/* create dialog box */
popup = CreateDialogBox(MessageText, buttons, ENTRIES(buttons));
StartDialog(popup);
/* wait for dialog to complete */
DialogEventLoop(&ReturnCode);
EndDialog(popup);
}
/* ---------------------------------------------------------------------------
* displays a single line prompt (message)
*/
void MessagePrompt(char *MessageText)
{
/* set some resources for the input fields */
if (!MessageText || !*MessageText)
{
XUnmapWindow(Dpy, XtWindow(Output.Message));
XMapWindow(Dpy, XtWindow(Output.StatusLine));
}
else
{
XtVaSetValues(Output.Message, XtNlabel, EMPTY(MessageText), NULL);
XUnmapWindow(Dpy, XtWindow(Output.StatusLine));
XMapWindow(Dpy, XtWindow(Output.Message));
}
}
/* ---------------------------------------------------------------------------
* called by action ActionFinishInputDialog() to indicate that a user input
* is finished. The passed parameter signals either OK (True) or Cancel
*/
void FinishInputDialog(Boolean OK)
{
ReturnCode = OK ? OK_BUTTON : CANCEL_BUTTON;
}
/* ---------------------------------------------------------------------------
* since all my dialogs are modal the X server wont create 'EnterNotify'
* events during the dialog is popped up. This breaks the crosshair
* visibility management. Therefore I check if the pointer is inside
* the output window and generate a 'EnterNotify' event.
*/
static void SendEnterNotify(void)
{
XEnterWindowEvent event;
Window root, child;
int root_x, root_y,
child_x, child_y;
unsigned int mask;
if (XQueryPointer(Dpy, Output.OutputWindow, &root, &child,
&root_x, &root_y, &child_x, &child_y, &mask))
{
event.type = EnterNotify;
event.display = Dpy;
event.window = Output.OutputWindow;
event.root = root;
XSendEvent(Dpy, Output.OutputWindow, True,
EnterWindowMask, (XEvent *) &event);
}
}
/* ---------------------------------------------------------------------------
* gets a string from user, memory is allocated for the string,
* the user is responsible for releasing the allocated memory
* string might be empty if flag is set
*/
char *GetUserInput(char *MessageText, char *OutputString)
{
char *string;
Widget inputfield;
/* display single line message */
MessagePrompt(MessageText);
/* the input field itself */
inputfield = XtVaCreateManagedWidget("inputField", asciiTextWidgetClass,
Output.MasterForm,
XtNresizable, True,
XtNresize, XawtextResizeWidth,
XtNstring, EMPTY(OutputString),
XtNwrap, XawtextWrapNever,
XtNeditType, XawtextEdit,
XtNfromHoriz, Output.Message,
XtNfromVert, Output.Viewport,
LAYOUT_BOTTOM,
NULL);
/* set focus to input field, override default translations
* and install accelerators
* grap all events --> make widget modal
*/
XtSetKeyboardFocus(Output.Toplevel, inputfield);
XtOverrideTranslations(inputfield,
XtParseTranslationTable(InputTranslations));
XtInstallAccelerators(inputfield, Output.MasterForm);
XtAddGrab(inputfield, True, False);
XtRealizeWidget(inputfield);
/* wait for input to complete and allocate memory if necessary */
if (DialogEventLoop(&ReturnCode) == OK_BUTTON)
{
/* strip white space and return string */
XtVaGetValues(inputfield, XtNstring, &string, NULL);
string = StripWhiteSpaceAndDup(string);
}
else
string = NULL;
/* restore normal outfit */
XtRemoveGrab(inputfield);
XtDestroyWidget(inputfield);
MessagePrompt(NULL);
/* force an 'EnterNotify' event if the pointer has moved
* into the output area
*/
SendEnterNotify();
XSync(Dpy, False);
return(string);
}
/* ---------------------------------------------------------------------------
* pops up and 'About' dialog
*/
void AboutDialog(void)
{
Widget popup,
dialog;
Pixmap icon = BadAlloc;
static DialogButtonType button =
{ "defaultButton", " OK ", CB_OK, (XtPointer) OK_BUTTON, NULL };
/* create dialog box */
popup = CreateDialogBox(
"This is PCB, an interactive\n"
"printed circuit board editor\n"
"version "RELEASE"\n\n"
"by Thomas Nau (c) 1994\n\n"
"If you have problems, hints or\n"
"suggestions, send mail to:\n"
"Thomas.Nau@rz.uni-ulm.de\n\n",
&button, 1);
if ((dialog = XtNameToWidget(popup, "dialog")) != NULL)
{
Screen *screen = XtScreen(Output.Toplevel);
if ((icon = XCreatePixmapFromBitmapData(Dpy,
XtWindow(Output.Toplevel), icon_bits, icon_width, icon_height,
BlackPixelOfScreen(screen), WhitePixelOfScreen(screen),
DefaultDepthOfScreen(screen))) != BadAlloc)
{
XtVaSetValues(dialog, XtNicon, icon, NULL);
}
}
StartDialog(popup);
/* wait for dialog to complete */
DialogEventLoop(&ReturnCode);
EndDialog(popup);
if (icon != BadAlloc)
XFreePixmap(Dpy, icon);
}
/* ----------------------------------------------------------------------
* confirmation dialog
*/
Boolean ConfirmDialog(char *MessageText)
{
Widget popup;
static DialogButtonType buttons[] = {
{ "defaultButton", "No/Cancel", CB_OK, (XtPointer) CANCEL_BUTTON, NULL},
{ "okButton", " OK ", CB_OK, (XtPointer) OK_BUTTON, NULL}};
/* create dialog box */
popup = CreateDialogBox(MessageText, buttons, ENTRIES(buttons));
StartDialog(popup);
/* wait for dialog to complete */
DialogEventLoop(&ReturnCode);
EndDialog(popup);
return(ReturnCode == OK_BUTTON);
}